import userService from 'SERVICE/userService';
import {
  setUserToken,
  clearToken,
  setUserTokenToLocalStorage
} from 'UTIL/commonUtil';
import { base64Encode, AESDecode, DESEncrypt } from '../../utils/commonUtil';
import { socketLogin, socketLogout } from '../../utils/SocketClient';
import {Toast} from 'antd-mobile';
// ================================
// Action Type
// ================================
const LOG_IN = 'LOG_IN';
const LOG_OUT = 'LOG_OUT';
const LOG_FAILED = 'LOG_FAILED';
const BEFORE_REQ = 'BEFORE_REQ';
const GET_USER_INFO = 'GET_USER_INFO';
const UPDATE_USER_INFO = 'UPDATE_USER_INFO';
const SET_ACTIVIED_INDEX = 'SET_ACTIVIED_INDEX';

let keepAlive; // 定时器
// ================================
// Action Creator
// ================================
const loginDone = (userData, loginName, password, base64Indi) => ({
  type: LOG_IN,
  payload: userData,
  loginName,
  password,
  base64Indi
});

const loginFailed = userData => ({
  type: LOG_FAILED,
  payload: userData
});
const logoutDone = userData => ({
  type: LOG_OUT
  // payload: userData,
});
const beforeReq = userData => ({
  type: BEFORE_REQ
});
const getUserInfoDone = userData => ({
  type: GET_USER_INFO,
  payload: userData
});

const updateUserInfoDone = userData => ({
  type: UPDATE_USER_INFO,
  payload: userData
});

function loginDoneDataFlow(token, loginName, password) {
  let curDate = new Date().toLocaleDateString().replace(/\//g, '-');
  let indiTokenStr;
  // var loginFlag;
  if (loginName && password) {
    setUserTokenToLocalStorage(token, loginName, password);
  } else {
    loginName = localStorage.getItem('loginName');
    password = localStorage.getItem('password');
  }
  indiTokenStr =
    'date=' +
    curDate +
    '&' +
    'password=' +
    AESDecode(password) +
    '&' +
    'username=' +
    loginName;
  let tokenStr = base64Encode(indiTokenStr);
  return tokenStr;
}

const login = (loginName, password, userAuthToken) => {
  return dispatch => {
    if (loginName && password) {
      dispatch(beforeReq());
    }
    userService
      .login({
        loginName: loginName,
        password: password,
        userAuthToken: userAuthToken
      })
      .then(
        re => {
          setUserToken(re.token);
          // setUserTokenToLocalStorage(re.token, loginName, password);
          let base64Indi = loginDoneDataFlow(re.token, loginName, password);
          // 登录成功后，发送心跳检测，保持token有效
          keepAlive = window.setInterval(() => {
            console.log('logining');
            dispatch(checkLogin(re.token));
          }, 5 * 60 * 1000);
          // 捕获登录失效
          let callbackFunc = event => {
            clearToken(localStorage.getItem('userAuthToken'));
            localStorage.clear();
            dispatch(logoutDone());
            Toast.fail('登录过期，请重新登录！');
            // this.context.router.replace('/redirect?dest=/');
            document.removeEventListener('isLoginInvalid', callbackFunc);
          };
          document.addEventListener('isLoginInvalid', callbackFunc);
          dispatch(loginDone(re, loginName, password, base64Indi));
        },
        err => {
          console.log(err);
          clearToken(localStorage.getItem('userAuthToken'));
          localStorage.clear();
          dispatch(loginFailed(err));
        }
      );
  };
};

const checkLogin = userAuthToken => {
  return dispatch => {
    userService.keepAlive().then(re => {});
  };
};

const logout = token => {
  return dispatch => {
    userService.logout().then(() => {
      clearToken(token);
      socketLogout(localStorage.getItem('loginName'));
      localStorage.clear();
      dispatch(logoutDone());
    });
  };
};

const getUserInfo = loginName => {
  return dispatch => {
    userService.getUserInfo({ loginName: loginName }).then(
      re => {
        dispatch(getUserInfoDone(re));
      },
      err => {
        console.log(err);
      }
    );
  };
};
const updateUserInfo = (loginName, userProfiles) => {
  return dispatch => {
    userService.updateUserInfo(loginName, userProfiles).then(
      re => {
        dispatch(updateUserInfoDone(re));
      },
      err => {
        console.log(err);
      }
    );
  };
};

const setActivedIndex = activedIndex => {
  return dispatch => {
    dispatch({
      type: SET_ACTIVIED_INDEX,
      payload: activedIndex
    });
  };
};
/* default 导出所有 Actions Creator */
export default {
  login,
  checkLogin,
  logout,
  getUserInfo,
  updateUserInfo,
  setActivedIndex
};

// ================================
// Action handlers for Reducer
// 本来更新 state 是 Reducer 的责任
// 但要把 ActionType 导出又引入实在太麻烦
// 且在 Reducer 中写 switch-case 实在太不优雅
// 故在此直接给出处理逻辑
// ================================
export const ACTION_HANDLERS = {
  [LOG_IN]: (userData, { payload, loginName, password, base64Indi }) => {
    let str;
    if (loginName && password) {
      str = loginName + '\t' + AESDecode(password);
    } else {
      str =
        localStorage.getItem('loginName') +
        AESDecode(localStorage.getItem('password'));
    }
    let giwsTk = DESEncrypt(str, 'xb&19AO.0t#8I');
    socketLogin(loginName);
    return {
      ...userData,
      indiToken: base64Indi,
      giwsToken: giwsTk,
      isLoginSuccess: 'loginSuccess',
      isRequesting: 'RequestDone',
      userAuthToken: payload.token,
      loginName: loginName ? loginName : localStorage.getItem('loginName'),
      ...payload
    };
  }, // payload is userData

  [LOG_FAILED]: (userData, { payload }) => {
    clearToken(localStorage.getItem('userAuthToken'));
    localStorage.clear();
    window.clearInterval(keepAlive);
    // this.context.router.replace('/redirect?dest=/');

    // history.goBack();
    return {
      ...userData,
      isLoginSuccess: 'logout',
      isRequesting: 'RequestDone',
      errorCode: payload.errorCode,
      ...payload
    };
  },
  [LOG_OUT]: (userData, { errMessage }) => {
    let initUserData = {
      errorMessage: '',
      indiToken: '',
      gwisToken: '',
      isRequesting: '',
      userAuthToken: '',
      loginName: '',
      userInfo: {
        userName: '',
        email: '',
        phone: '',
        mobilePhone: '',
        department: '',
        address: '',
        nativePlace: '',
        inChargeSystem: '',
        group: ''
      },
      userPageTabActiveIndex: 0
    };
    clearToken(localStorage.getItem('userAuthToken'));
    localStorage.clear();
    userData = initUserData;
    window.clearInterval(keepAlive);
    return { ...userData, isLoginSuccess: 'logout' };
  },
  [BEFORE_REQ]: userData => {
    return { ...userData, errorMessage: '', isRequesting: 'Requesting' };
  },
  [GET_USER_INFO]: (userData, { payload }) => {
    let tmpInfo = payload;
    payload.updateFlag = false;
    return {
      ...userData,
      userInfo: tmpInfo,
      ...payload
    };
  },
  [UPDATE_USER_INFO]: (userData, { payload }) => {
    return {
      ...userData,
      ...payload
    };
  },
  [SET_ACTIVIED_INDEX]: (userData, { payload }) => {
    return {
      ...userData,
      userPageTabActiveIndex: payload
    };
  }
};
